﻿Imports System.Reflection



Public Class DataFilterTypeCollection(Of T)
    Inherits CollectionBase

    Protected Friend iCriteriaOperator As CriteriaOperators = CriteriaOperators.co_AND
    Protected Friend iTableName As String

    Public Sub New(ByVal TableName As String)
        Me.iTableName = TableName
    End Sub

    Public Property CriteriaOperator() As CriteriaOperators
        Get
            Return Me.iCriteriaOperator
        End Get
        Set(ByVal value As CriteriaOperators)
            Me.iCriteriaOperator = value
        End Set
    End Property

    Default Public Property Item(ByVal Index As Integer) As DataFilterType(Of T)
        Get
            Return CType(Me.List.Item(Index), DataFilterType(Of T))
        End Get
        Set(ByVal value As DataFilterType(Of T))
            Me.List.Item(Index) = value
        End Set
    End Property

    Public Overridable Function GetSQL() As String
        Dim sql As String = ""
        Dim op As String = IIf(Me.CriteriaOperator = CriteriaOperators.co_AND, "AND", "OR")
        Dim df As DataFilterTypeBase(Of T)
        For Each df In Me.List
            If df.GetType().Name = GetType(DataFilterType(Of T)).Name Then
                If IsDate(df.iValue) Then
                    If (sql <> "") And (sql.EndsWith("AND") = False Or sql.EndsWith("OR") = False) Then
                        '(LMDate Between '2007-06-05 00:00:00.000' and '2007-06-05 23:59:59.999')
                        sql = sql & " " & op & _
                                " ([" & Me.iTableName & "].[" & df.iFieldName & "] Between '" & _
                                Format(CType(df.iValue, DateTime), "yyyy-MM-dd") & " 00:00:00.000' And '" & _
                                Format(CType(df.iValue, DateTime), "yyyy-MM-dd") & " 23:59:59.998') "
                    Else
                        sql = sql & " ([" & Me.iTableName & "].[" & df.iFieldName & "] Between '" & _
                                Format(CType(df.iValue, DateTime), "yyyy-MM-dd") & " 00:00:00.000' And '" & _
                                Format(CType(df.iValue, DateTime), "yyyy-MM-dd") & " 23:59:59.998') "
                    End If
                Else
                    If (sql <> "") And (sql.EndsWith("AND") = False Or sql.EndsWith("OR") = False) Then
                        sql = sql & " " & op & _
                            " [" & Me.iTableName & "].[" & df.iFieldName & "]='" & df.iValue & "' "
                    Else
                        sql = sql & " [" & Me.iTableName & "].[" & df.iFieldName & "]='" & df.iValue & "' "
                    End If
                End If
            Else
                If (sql <> "") And (sql.EndsWith("AND") = False Or sql.EndsWith("OR") = False) Then
                    sql = sql & " " & op & df.GetSQL
                Else
                    sql = sql & df.GetSQL
                End If
            End If
        Next
        If Me.List.Count > 0 Then sql = " Where " & sql
        Return sql
    End Function

#Region "Add Overloads"
    Public Overridable Function Add(ByVal FieldName As T) As Integer
        Return Me.List.Add(New SimpleDataFilterType(Of T)(Me.iTableName, FieldName.ToString))
    End Function
    Public Overridable Function Add(ByVal FieldName As T, ByVal Value As String) As Integer
        Return Me.List.Add(New SimpleDataFilterType(Of T)(Me.iTableName, FieldName.ToString, Value))
    End Function
    Public Overridable Function Add(ByVal FieldName As T, ByVal StartValue As String, ByVal EndValue As String) As Integer
        Return Me.List.Add(New RangeDataFilterType(Of T)(Me.iTableName, FieldName.ToString, StartValue, EndValue))
    End Function
#End Region

#Region "Base Implementations"
    Public Overridable Function IndexOf(ByVal value As DataFilterTypeBase(Of T)) As Integer
        Return Me.List.IndexOf(value)
    End Function
    Public Overridable Sub Insert(ByVal index As Integer, ByVal value As DataFilterTypeBase(Of T))
        Me.List.Insert(index, value)
    End Sub
    Public Overridable Overloads Sub Remove(ByVal value As DataFilterTypeBase(Of T))
        Me.List.Remove(value)
    End Sub
    Public Overridable Function Contains(ByVal value As DataFilterTypeBase(Of T)) As Boolean
        Return Me.List.Contains(value)
    End Function
    Protected NotOverridable Overrides Sub OnValidate(ByVal value As Object)
        'If Not GetType(DataFilterTypeBase(Of T)).IsAssignableFrom(value.GetType()) Then
        '    Throw New ArgumentException("Value must be of type SimpleDataFilterType or RangeDataFilterType")
        'End If
    End Sub
    Protected NotOverridable Overrides Sub OnInsert(ByVal index As Integer, ByVal value As Object)
        MyBase.OnInsert(index, value)
    End Sub
    Protected NotOverridable Overrides Sub OnRemove(ByVal index As Integer, ByVal value As Object)
        MyBase.OnRemove(index, value)
    End Sub
    Protected NotOverridable Overrides Sub OnSet(ByVal index As Integer, ByVal oldValue As Object, ByVal newValue As Object)
        MyBase.OnSet(index, oldValue, newValue)
    End Sub
#End Region

End Class

Public Enum CriteriaOperators
    co_AND
    co_OR
End Enum

